﻿using SBB.Services.SFTP.Client;
using SBSftpCommon;
using SBSimpleSftp;
using SBSSHKeyStorage;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;

namespace RemoteEP
{
    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.PerCall)]
    public class EAIEndpointService : IEAIEndpointService
    {
        private MSLogger _logger = new MSLogger();

        public EAIEndpointService()
        {
            SBUtils.Unit.SetLicenseKey(ConfigurationManager.AppSettings["SBBKey"]);
        }

        public string Ping()
        {
            return String.Format("{0}:{1} Is Working", System.Environment.MachineName, System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
        }

        public TransactionItemsComposite Submit(TransactionItemsComposite TransferredContent)
        {
            TElSimpleSFTPClient sftpClient = new TElSimpleSFTPClient();
            sftpClient.AuthenticationTypes = SBSSHConstants.Unit.SSH_AUTH_TYPE_PASSWORD;
            sftpClient.OnKeyValidate += new SBSSHCommon.TSSHKeyValidateEvent(onKeyValidate);

            sftpClient.Address = TransferredContent.FtpAddress;
            sftpClient.Port = TransferredContent.PortNumber;
            sftpClient.Username = TransferredContent.UserIDForThirdParty;
            sftpClient.Password = TransferredContent.PasswordForThirdParty;

            _logger.Debug(String.Format("Server Address from client: [{0}]", TransferredContent.FtpAddress));
            _logger.Debug(String.Format("Server Port from client: [{0}]", TransferredContent.PortNumber));
            _logger.Debug(String.Format("Server Username from client: [{0}]", TransferredContent.UserIDForThirdParty));
            _logger.Debug(String.Format("Server Password from client: [{0}]", TransferredContent.PasswordForThirdParty));

            sftpClient.Open();

            foreach (var payload in TransferredContent.myPayload) {
                if (TransferredContent.OverwriteifExists) {
                    using (var stream = new MemoryStream(payload.fileArray)) {
                        sftpClient.UploadStream(stream, payload.fileName, SBTypes.TSBFileTransferMode.ftmOverwrite);
                    }
                } else {
                    var files = new ArrayList();
                    sftpClient.ListDirectory("/", files, "*.*", true, true, false);

                    var fileNameExists = fileNameExistsOnRemote(files, payload.fileName);

                    if (fileNameExists) {
                        var fileName = Path.GetFileNameWithoutExtension(payload.fileName);
                        var ext = Path.GetExtension(payload.fileName);
                        var fileNumericInc = 1;
                        var created = false;

                        while (!created && fileNumericInc < 100) {
                            var newFileName = String.Format("{0}{1}{2}", fileName, fileNumericInc, ext);

                            if (!fileNameExistsOnRemote(files, newFileName)) {
                                using (var stream = new MemoryStream(payload.fileArray)) {
                                    sftpClient.UploadStream(stream, newFileName, SBTypes.TSBFileTransferMode.ftmOverwrite);
                                }

                                created = true;
                            } else {
                                fileNumericInc++;
                            }
                        }

                        if (fileNumericInc >= 100) {
                            //TODO: Add logging here in the event of the file increment number growing to 100
                        }
                    } else {
                        using (var stream = new MemoryStream(payload.fileArray)) {
                            sftpClient.UploadStream(stream, payload.fileName, SBTypes.TSBFileTransferMode.ftmOverwrite);
                        }
                    }
                }
            }

            return new TransactionItemsComposite();
        }

        private void onKeyValidate(object sender, TElSSHKey key, ref bool isValid)
        {
            //TODO: Implement proper public key validation here
            isValid = true;
        }

        private bool fileNameExistsOnRemote(ArrayList fileInfos, string fileName)
        {
            var fileNameExists = false;
            foreach (var file in fileInfos) {
                var fileInfo = (TElSftpFileInfo)file;
                if (fileInfo.Name == fileName) {
                    fileNameExists = true;
                    break;
                }
            }

            return fileNameExists;
        }
    }
}
